Overview
The 6502 is an 8-bit microprocessor released by MOS Technology in 1975. It has an 8-bit data bus and a 16-bit address bus allowing it to access 64 KiB of memory. It was designed as a cheaper version of the Motorola 6800 and many of the designers from the Motorola project also worked on the 6502. Being simpler and cheaper than its rivals it found widespread use in 8-bit microcomputers like the Commodore PET, Commodore 64, NES, BBC Micro, Apple II and the Atari 8-bit line.
CPU Registers
The 6502 has three 8-bit data registers, the accumulator and two index registers.
It also has a 16-bit program counter (PC) register and an 8-bit stack-pointer (S) register. The S register is treaded as a 16-bit register but the upper 8-bits are always 0000 0001. The 6502 also has a Processor status (P) register that holds the status flags.
Condition Flags
The 6502 has 7 flags that are set by various instructions.
Carry/Borrow
Updated to indicate if a carry/borrow occurs as the result of an arithmetic instruction or as an additional bit of data used by other instructions.
Zero
Set if the result of an operation is zero.
Interrupt Disable
Set by default and must be cleared if interrupts are desired
Decimal Mode
Set to indicate that add and subtract operations should treat values as binary-coded-decimal (BCD) instead of binary.
Break Command
Set if an interrupt was triggered by the BRK command.
Overflow
Indicates that an overflow occurred during an add or subtract operation
Negative
Set based on the most-significant bit of the value in the accumulator to indicate the sign of the result.
Stack Operations
The stack location is set by loading a value into S and it expands downwards in memory. Because the upper 8-bits of S are fixed the stack is limited to 256 bytes and is always in a fixed location in memory.
Addressing Modes
The 6502 has 12 addressing modes which dictate how the bytes of the instruction are interpreted.
Accumulator
A one byte instruction with the operand of the instruction being the accumulator
Immediate
A two byte instruction with the second byte being a constant value to be used by the instruction
Zero Page
A two byte instruction with the second byte being an address in the zero page (First 256 bytes of memory) used by the instruction.
Zero Page, X
A two byte instruction with the second byte being a base address in the zero page (First 256 bytes of memory). The X Index register is added to the base address to give the effective address to be used by the instruction.
Note that the high-byte of the address is forced to be 0 for Zero Page operations so the index calculation can cause a warp around.
Zero Page, Y
A two byte instruction with the second byte being a base address in the zero page (First 256 bytes of memory). The Y Index register is added to the base address to give the effective address to be used by the instruction.
Note that the high-byte of the address is forced to be 0 for Zero Page operations so the index calculation can cause a warp around.
Absolute
A three byte instruction with the second and third bytes specifying an address to be used by the instruction. The address is stored low-order byte first.
Absolute, X
A three byte instruction with the second and third bytes specifying a base address. The address is stored low-order byte first. The X Index register is added to the base address to give the effective address to be used by the instruction.
Absolute, Y
A three byte instruction with the second and third bytes specifying a base address. The address is stored low-order byte first. The Y Index register is added to the base address to give the effective address to be used by the instruction.
Implied
A single byte instruction with the opcode specifying the parameters of the instruction
Relative
A two byte instruction with the second byte being a signed offset that specifies the address to use for the instruction.
Note the the offset is relative to the start of the next instruction in memory as the PC will be pointing to that location when the offset is applied.
(Indirect, X)
A two byte instruction with the second byte being a base address in the zero page (First 256 bytes of memory). The X Index register is added to the base address and then the two bytes at that location are used as the effective address for the instruction. The address in the zero page is stored low-order byte first.
(Indirect), Y
A two byte instruction with the second byte being a base address in the zero page (First 256 bytes of memory). The Y index register is added to the two bytes at that location and the result is used as the effective address for the instruction. The address in the zero page is stored low-order byte first.
Absolute Indirect
A three byte instruction with the second and third bytes specifying an address. Two bytes are loaded from this location and used as the effective address for the instruction. Both addresses are stored low-order byte first.
Instruction Set
Data
<int8> indicates a signed 8-bit value
<uint8> indicates an unsigned 8-bit value
<addr8> indicates a 8-bit zero page address
<addr16> indicates a 16-bit address in little endian form
Data Transfer Instructions
LDA
Loads the specified value into the Accumulator
Instruction | Addressing Mode | Binary Format | Octal | Hex |
LDA (<ZP Address>, X) | (Indirect, X) | 10100001 <addr8> | 241 | A1 |
LDA <ZP Address> | Zero Page | 10100101 <addr8> | 245 | A5 |
LDA #<Data> | Immediate | 10101001 <int8> | 251 | A9 |
LDA <Address> | Absolute | 10101101 <addr16> | 255 | AD |
LDA (<ZP Address>), Y | (Indirect), Y | 10110001 <addr8> | 261 | B1 |
LDA <ZP Address>, X | Zero Page, X | 10110101 <addr8> | 265 | B5 |
LDA <Address>, Y | Absolute, Y | 10111001 <addr16> | 271 | B9 |
LDA <Address>, X | Absolute, X | 10111101 <addr16> | 275 | BD |
LDX
Loads the specified value into the X Register
Instruction | Addressing Mode | Binary Format | Octal | Hex |
LDX #<Data> | Immediate | 10100010 <int8> | 242 | A2 |
LDX <ZP Address> | Zero Page | 10100110 <addr8> | 246 | A6 |
LDX <Address> | Absolute | 10101110 <addr16> | 256 | AE |
LDX <ZP Address>, Y | Zero Page, Y | 10110110 <addr8> | 266 | B6 |
LDX <Address>, Y | Absolute, Y | 10111110 <addr16> | 276 | BE |
LDY
Loads the specified value into the Y Register
Instruction | Addressing Mode | Binary Format | Octal | Hex |
LDY #<Data> | Immediate | 10100000 <int8> | 240 | A0 |
LDY <ZP Address> | Zero Page | 10100100 <addr8> | 244 | A4 |
LDY <Address> | Absolute | 10101100 <addr16> | 254 | AC |
LDY <ZP Address>, X | Zero Page, X | 10110100 <addr8> | 264 | B4 |
LDY <Address>, X | Absolute, X | 10111100 <addr16> | 274 | BC |
STA
Stores the value in the Accumulator at the specified location
Instruction | Addressing Mode | Binary Format | Octal | Hex |
STA (<ZP Address>, X) | (Indirect, X) | 10000001 <addr8> | 201 | 81 |
STA <ZP Address> | Zero Page | 10000101 <addr8> | 205 | 85 |
STA <Address> | Absolute | 10001101 <addr16> | 215 | 8D |
STA (<ZP Address>), Y | (Indirect), Y | 10010001 <addr8> | 221 | 91 |
STA <ZP Address>, X | Zero Page, X | 10010101 <addr8> | 225 | 95 |
STA <Address>, Y | Absolute, Y | 10011001 <addr16> | 231 | 99 |
STA <Address>, X | Absolute, X | 10011101 <addr16> | 235 | 9D |
STX
Stores the value in the X Register at the specified location
Instruction | Addressing Mode | Binary Format | Octal | Hex |
STX <ZP Address> | Zero Page | 10000110 <addr8> | 206 | 86 |
STX <Address> | Absolute | 10001110 <addr16> | 216 | 8E |
STX <ZP Address>, Y | Zero Page, Y | 10010110 <addr8> | 226 | 96 |
STY
Stores the value in the Y Register at the specified location
Instruction | Addressing Mode | Binary Format | Octal | Hex |
STY <ZP Address> | Zero Page | 10000100 <addr8> | 204 | 84 |
STY <Address> | Absolute | 10001100 <addr16> | 214 | 8C |
STY <ZP Address>, X | Zero Page, X | 10010100 <addr8> | 224 | 94 |
Register Transfer Instructions
TAX
Transfer the value in the Accumulator to the X Register
Instruction | Addressing Mode | Binary Format | Octal | Hex |
TAX | Implied | 10101010 | 252 | AA |
TAY
Transfer the value in the Accumulator to the Y Register
Instruction | Addressing Mode | Binary Format | Octal | Hex |
TAY | Implied | 10101000 | 250 | A8 |
TXA
Transfer the value in the X Register to the Accumulator
Instruction | Addressing Mode | Binary Format | Octal | Hex |
TXA | Implied | 10001010 | 212 | 8A |
TYA
Transfer the value in the Y Register to the Accumulator
Instruction | Addressing Mode | Binary Format | Octal | Hex |
TSX | Implied | 10011000 | 230 | 98 |
TSX
Transfer the Stack Pointer to the X Register
Instruction | Addressing Mode | Binary Format | Octal | Hex |
TYA | Implied | 10111010 | 272 | BA |
TXS
Transfer the value in the X Register to the Stack Pointer
Instruction | Addressing Mode | Binary Format | Octal | Hex |
TXS | Implied | 10011010 | 232 | 9A |
Addition Instruction
ADC
Adds the specified value and the carry bit to the Accumulator. The result is stored in the Accumulator.
Instruction | Addressing Mode | Binary Format | Octal | Hex |
ADC (<ZP Address>, X) | (Indirect, X) | 01100001 <addr8> | 141 | 61 |
ADC <ZP Address> | Zero Page | 01100101 <addr8> | 145 | 65 |
ADC #<Data> | Immediate | 01101001 <int8> | 151 | 69 |
ADC <Address> | Absolute | 01101101 <addr16> | 155 | 6D |
ADC (<ZP Address>), Y | (Indirect), Y | 01110001 <addr8> | 161 | 71 |
ADC <ZP Address>, X | Zero Page, X | 01110101 <addr8> | 165 | 75 |
ADC <Address>, Y | Absolute, Y | 01111001 <addr16> | 171 | 79 |
ADC <Address>, X | Absolute, X | 01111101 <addr16> | 175 | 7D |
Subtraction Instruction
SBC
Subtracts the specified value and the borrow bit from the Accumulator. The result is stored in the Accumulator.
Instruction | Addressing Mode | Binary Format | Octal | Hex |
SBC (<ZP Address>, X) | (Indirect, X) | 11100001 <addr8> | 341 | E1 |
SBC <ZP Address> | Zero Page | 11100101 <addr8> | 345 | E5 |
SBC #<Data> | Immediate | 11101001 <int8> | 351 | E9 |
SBC <Address> | Absolute | 11101101 <addr16> | 355 | ED |
SBC (<ZP Address>), Y | (Indirect), Y | 11110001 <addr8> | 361 | F1 |
SBC <ZP Address>, X | Zero Page, X | 11110101 <addr8> | 365 | F5 |
SBC <Address>, Y | Absolute, Y | 11111001 <addr16> | 371 | F9 |
SBC <Address>, X | Absolute, X | 11111101 <addr16> | 375 | FD |
Increment/Decrement Instructions
DEC
Subtracts 1 from the specified value and stores the result in the same location
Instruction | Addressing Mode | Binary Format | Octal | Hex |
DEC <ZP Address> | Zero Page | 11000110 <addr8> | 306 | C6 |
DEC <Address> | Absolute | 11001110 <addr16> | 316 | CE |
DEC <ZP Address>, X | Zero Page, X | 11010110 <addr8> | 326 | D6 |
DEC <Address>, X | Absolute, X | 11011110 <addr16> | 336 | DE |
DEX
Subtracts 1 from the X Register and stores the result in the X Register
Instruction | Addressing Mode | Binary Format | Octal | Hex |
DEX | Implied | 11001010 | 312 | CA |
DEY
Subtracts 1 from the Y Register and stores the result in the Y Register
Instruction | Addressing Mode | Binary Format | Octal | Hex |
DEY | Implied | 10001000 | 210 | 88 |
INC
Add 1 to the specified value and stores the result in the same location
Instruction | Addressing Mode | Binary Format | Octal | Hex |
INC <ZP Address> | Zero Page | 11100110 <addr8> | 346 | E6 |
INC <Address> | Absolute | 11101110 <addr16> | 356 | EE |
INC <ZP Address>, X | Zero Page, X | 11110110 <addr8> | 366 | F6 |
INC <Address>, X | Absolute, X | 11111110 <addr16> | 376 | FE |
INX
Add 1 to the X Register and stores the result in the X Register
Instruction | Addressing Mode | Binary Format | Octal | Hex |
INX | Implied | 11101000 | 350 | E8 |
INY
Add 1 to the Y Register and stores the result in the Y Register
Instruction | Addressing Mode | Binary Format | Octal | Hex |
INY | Implied | 11001000 | 310 | C8 |
Rotate/Shift Instructions
ASL
Shifts the specified value Left one bit. The High-order bit is placed in the carry flag and the low order bit is set to 0. The result is stored in the same location.
Instruction | Addressing Mode | Binary Format | Octal | Hex |
ASL <ZP Address> | Zero Page | 00000110 <addr8> | 006 | 06 |
ASL A | Accumulator | 00001010 | 012 | 0A |
ASL <Address> | Absolute | 00001110 <addr16> | 016 | 0E |
ASL <ZP Address>, X | Zero Page, X | 00010110 <addr8> | 026 | 16 |
ASL <Address>, X | Absolute, X | 00011110 <addr16> | 036 | 1E |
LSR
Shifts the specified value right one bit. The low-order bit is placed in the carry flag and the high-order bit is set to 0. The result is stored in the same location.
Instruction | Addressing Mode | Binary Format | Octal | Hex |
LSR <ZP Address> | Zero Page | 01000110 <addr8> | 106 | 46 |
LSR A | Accumulator | 01001010 | 112 | 4A |
LSR <Address> | Absolute | 01001110 <addr16> | 116 | 4E |
LSR <ZP Address>, X | Zero Page, X | 01010110 <addr8> | 126 | 56 |
LSR <Address>, X | Absolute, X | 01011110 <addr16> | 136 | 5E |
ROL
Rotates the specified value left one bit. The high-order bit is placed in the carry flag and the low-order bit is set to the previous value of Carry Flag. The result is stored in the same location.
Instruction | Addressing Mode | Binary Format | Octal | Hex |
ROL <ZP Address> | Zero Page | 00100110 <addr8> | 046 | 26 |
ROL A | Accumulator | 00101010 <int8> | 052 | 2A |
ROL <Address> | Absolute | 00101110 <addr16> | 056 | 2E |
ROL <ZP Address>, X | Zero Page, X | 00110110 <addr8> | 066 | 36 |
ROL <Address>, X | Absolute, X | 00111110 <addr16> | 076 | 3E |
ROR
Rotates the specified value right one bit. The low-order bit is placed in the carry flag and the high-order bit is set to the previous value of Carry Flag. The result is stored in the same location.
Instruction | Addressing Mode | Binary Format | Octal | Hex |
ROR <ZP Address> | Zero Page | 01100110 <addr8> | 146 | 66 |
ROR A | Accumulator | 01101010 <int8> | 152 | 6A |
ROR <Address> | Absolute | 01101110 <addr16> | 156 | 6E |
ROR <ZP Address>, X | Zero Page, X | 01110110 <addr8> | 166 | 76 |
ROR <Address>, X | Absolute, X | 01111110 <addr16> | 176 | 7E |
Logical Instructions
AND
Logical ANDs the specified value with Accumulator. The result is stored in the Accumulator.
Instruction | Addressing Mode | Binary Format | Octal | Hex |
AND (<ZP Address>, X) | (Indirect, X) | 00100001 <addr8> | 041 | 21 |
AND <ZP Address> | Zero Page | 00100101 <addr8> | 045 | 25 |
AND #<Data> | Immediate | 00101001 <int8> | 051 | 29 |
AND <Address> | Absolute | 00101101 <addr16> | 055 | 2D |
AND (<ZP Address>), Y | (Indirect), Y | 00110001 <addr8> | 061 | 31 |
AND <ZP Address>, X | Zero Page, X | 00110101 <addr8> | 065 | 35 |
AND <Address>, Y | Absolute, Y | 00111001 <addr16> | 071 | 39 |
AND <Address>, X | Absolute, X | 00111101 <addr16> | 075 | 3D |
EOR
Logical Exclusive Or the specified value with Accumulator. The result is stored in the Accumulator.
Instruction | Addressing Mode | Binary Format | Octal | Hex |
EOR (<ZP Address>, X) | (Indirect, X) | 01000001 <addr8> | 101 | 41 |
EOR <ZP Address> | Zero Page | 01000101 <addr8> | 105 | 45 |
EOR #<Data> | Immediate | 01001001 <int8> | 111 | 49 |
EOR <Address> | Absolute | 01001101 <addr16> | 115 | 4D |
EOR (<ZP Address>), Y | (Indirect), Y | 01010001 <addr8> | 121 | 51 |
EOR <ZP Address>, X | Zero Page, X | 01010101 <addr8> | 125 | 55 |
EOR <Address>, Y | Absolute, Y | 01011001 <addr16> | 131 | 59 |
EOR <Address>, X | Absolute, X | 01011101 <addr16> | 135 | 5D |
ORA
Logical Or the specified value with Accumulator. The result is stored in the Accumulator.
Instruction | Addressing Mode | Binary Format | Octal | Hex |
ORA (<ZP Address>, X) | (Indirect, X) | 00000001 <addr8> | 001 | 01 |
ORA <ZP Address> | Zero Page | 00000101 <addr8> | 005 | 05 |
ORA #<Data> | Immediate | 00001001 <int8> | 011 | 09 |
ORA <Address> | Absolute | 00001101 <addr16> | 015 | 0D |
ORA (<ZP Address>), Y | (Indirect), Y | 00010001 <addr8> | 021 | 11 |
ORA <ZP Address>, X | Zero Page, X | 00010101 <addr8> | 025 | 15 |
ORA <Address>, Y | Absolute, Y | 00011001 <addr16> | 031 | 19 |
ORA <Address>, X | Absolute, X | 00011101 <addr16> | 035 | 1D |
Status Flag Instructions
CLC
Clear Carry Flag
Instruction | Addressing Mode | Binary Format | Octal | Hex |
CLC | Implied | 00011000 | 030 | 18 |
CLD
Clear Decimal Flag
Instruction | Addressing Mode | Binary Format | Octal | Hex |
CLD | Implied | 11011000 | 330 | D8 |
CLI
Clear Interrupt Disable Flag
Instruction | Addressing Mode | Binary Format | Octal | Hex |
CLI | Implied | 01011000 | 130 | 58 |
CLV
Clear Overflow Flag
Instruction | Addressing Mode | Binary Format | Octal | Hex |
CLV | Implied | 10111000 | 270 | B8 |
SEC
Set Carry Flag
Instruction | Addressing Mode | Binary Format | Octal | Hex |
SEC | Implied | 00111000 | 070 | 38 |
SED
Set Decimal Flag
Instruction | Addressing Mode | Binary Format | Octal | Hex |
SED | Implied | 11111000 | 370 | F8 |
SEI
Set Interrupt Disable Flag
Instruction | Addressing Mode | Binary Format | Octal | Hex |
SEI | Implied | 01111000 | 170 | 78 |
Compare Instructions
BIT
Logical ANDs the specified value with Accumulator. The result isn't stored but the zero flag will be set based on the result. The negative flag will contain bit 7 of the specified value and the overflow flag will contain bit 6 of the specified value.
Instruction | Addressing Mode | Binary Format | Octal | Hex |
BIT <ZP Address> | Zero Page | 00100100 <addr8> | 044 | 24 |
BIT <Address> | Absolute | 00101100 <addr16> | 054 | 2C |
CMP
Subtracts the specified value from the accumulator. The status flags are updated based on the result but the result isn't saved
Instruction | Addressing Mode | Binary Format | Octal | Hex |
CMP (<ZP Address>, X) | (Indirect, X) | 11000001 <addr8> | 301 | C1 |
CMP <ZP Address> | Zero Page | 11000101 <addr8> | 305 | C5 |
CMP #<Data> | Immediate | 11001001 <int8> | 311 | C9 |
CMP <Address> | Absolute | 11001101 <addr16> | 315 | CD |
CMP (<ZP Address>), Y | (Indirect), Y | 11010001 <addr8> | 321 | D1 |
CMP <ZP Address>, X | Zero Page, X | 11010101 <addr8> | 325 | D5 |
CMP <Address>, Y | Absolute, Y | 11011001 <addr16> | 331 | D9 |
CMP <Address>, X | Absolute, X | 11011101 <addr16> | 335 | DD |
CPX
Subtracts the specified value from the X Register. The status flags are updated based on the result but the result isn't saved
Instruction | Addressing Mode | Binary Format | Octal | Hex |
CPX #<Data> | Immediate | 11100000 <int8> | 340 | E0 |
CPX <ZP Address> | Zero Page | 11100100 <addr8> | 344 | E4 |
CPX <Address> | Absolute | 11101100 <addr16> | 354 | EC |
CPY
Subtracts the specified value from the Y Register. The status flags are updated based on the result but the result isn't saved
Instruction | Addressing Mode | Binary Format | Octal | Hex |
CPY #<Data> | Immediate | 11000000 <int8> | 300 | C0 |
CPY <ZP Address> | Zero Page | 11000100 <addr8> | 304 | C4 |
CPY <Address> | Absolute | 11001100 <addr16> | 314 | CC |
Branch Instructions
BCC
Branch to the specified address if carry flag is cleared
Instruction | Addressing Mode | Binary Format | Octal | Hex |
BCC <Offset> | Relative | 10010000 <int8> | 220 | 90 |
BCS
Branch to the specified address if carry flag is set
Instruction | Addressing Mode | Binary Format | Octal | Hex |
BCS <Offset> | Relative | 10110000 <int8> | 260 | B0 |
BEQ
Branch to the specified address if zero flag is set (equal)
Instruction | Addressing Mode | Binary Format | Octal | Hex |
BEQ <Offset> | Relative | 11110000 <int8> | 360 | F0 |
BMI
Branch to the specified address if negative flag is set (minus)
Instruction | Addressing Mode | Binary Format | Octal | Hex |
BMI <Offset> | Relative | 00110000 <int8> | 060 | 30 |
BNE
Branch to the specified address if zero flag is cleared (not equal)
Instruction | Addressing Mode | Binary Format | Octal | Hex |
BNE <Offset> | Relative | 11010000 <int8> | 320 | D0 |
BPL
Branch to the specified address if negative flag is cleared (plus)
Instruction | Addressing Mode | Binary Format | Octal | Hex |
BPL <Offset> | Relative | 00010000 <int8> | 020 | 10 |
BVC
Branch to the specified address if overflow flag is cleared
Instruction | Addressing Mode | Binary Format | Octal | Hex |
BVC <Offset> | Relative | 01010000 <int8> | 120 | 50 |
BVS
Branch to the specified address if overflow flag is set
Instruction | Addressing Mode | Binary Format | Octal | Hex |
BVS <Offset> | Relative | 01110000 <int8> | 160 | 70 |
Jump Instructions
JMP
Loads the Program Counter with the address specified
Instruction | Addressing Mode | Binary Format | Octal | Hex |
JMP <Address> | Absolute | 01001100 <addr16> | 114 | 4C |
JMP (<Address>) | Indirect | 01101100 <addr16> | 154 | 6C |
JSR
Stores the address of the last byte of the instruction on the stack. Loads the Program Counter with the address specified
Instruction | Addressing Mode | Binary Format | Octal | Hex |
JSR <Address> | Absolute | 00100000 <addr16> | 040 | 20 |
Return Instructions
RTI
Restores the Status Register from the Stack. Restores the Program Counter from the stack.
Instruction | Addressing Mode | Binary Format | Octal | Hex |
RTI | Implied | 01000000 | 100 | 40 |
RTS
Pops the Program Counter from the stack and adds one
Instruction | Addressing Mode | Binary Format | Octal | Hex |
RTS | Implied | 01100000 | 140 | 60 |
Stack Instructions
PHA
Pushes the value in the Accumulator on to the Stack
Instruction | Addressing Mode | Binary Format | Octal | Hex |
PHA | Implied | 01001000 | 110 | 48 |
PHP
Pushes the value in the Status Register on to the Stack
Instruction | Addressing Mode | Binary Format | Octal | Hex |
PHP | Implied | 00001000 | 010 | 08 |
PLA
Pulls a value from the stack and stores it in the Accumulator
Instruction | Addressing Mode | Binary Format | Octal | Hex |
PLA | Implied | 01101000 | 150 | 68 |
PLP
Pulls a value from the stack and stores it in the Status Register
Instruction | Addressing Mode | Binary Format | Octal | Hex |
PLP | Implied | 00101000 | 050 | 28 |
Machine Control Instructions
BRK
Force break. Sets the break flag.
Instruction | Addressing Mode | Binary Format | Octal | Hex |
BRK | Implied | 00000000 | 000 | 00 |
NOP
No Operation
Instruction | Addressing Mode | Binary Format | Octal | Hex |
NOP | Implied | 11101010 | 352 | EA |